

/**
* 设备保养表单，表格
* author Forjune
*/
import React, { useRef, useState, forwardRef, useEffect } from 'react'
import { Form, Input, Select, Button, Table, Radio, DatePicker, message } from 'antd'
import TitleLine from 'components/common/titleLine'
import DeviceMessage from 'components/common/deviceMessage'
import MaintenanceMesssage from 'components/common/maintenanceMessage'
import PreviewPlanModal from 'components/common/previewPlanModal'
import { addUpkeep, getUpkeepDetail, editUpkeep } from 'service/actions/deviceUpkeep'
import { getDeviceDetail } from 'service/actions/dictionaryList'
import moment from 'moment'
import router from 'umi/router'
import { withRouter } from 'umi'
import { connect } from 'dva'
import tools from 'columns/tools'
import './index.styl'
import { randomString } from 'utils/format'
import { fitterInput } from 'utils/filters'

const { Option } = Select
const RefDeviceMessage = forwardRef((props, ref) => (
  <DeviceMessage {...props} cRef={ref} />
));
const RefMaintenanceMesssage = forwardRef((props, ref) => (
  <MaintenanceMesssage {...props} cRef={ref} />
));

function Plan(props) {
  const {
    dispatch,
    id,
    location,
    deviceUpkeep: { parameter },
    dictionaryList: { deviceList, presetList, userList },
    headerTaps: { panes },
    form,
  } = props

  const { getFieldDecorator, validateFields, setFieldsValue } = form
  const [tableData, setTableData] = useState([])
  const [verifyTip, setVerifyTip] = useState('')
  // 数据状态
  const [status, setStatus] = useState('')
  const [deviceObj, setDeviceObj] = useState({
    deviceId: '',
    defaultDevice: '',
    deviceDetail: {}
  })
  const [maintainObj, setMaintainObj] = useState({
    maintainUser: '',
    defaultMaintenance: '',
    maintenanceMes: {}
  })
  const [planInfoObj, setPlanInfoObj] = useState({})
  const [paramsObj, setParamsObj] = useState({})

  useEffect(() => {
    async function fetchData() {
      if (id !== undefined) {
        const data = await getUpkeepDetail({
          id,
          method: 'GET'
        })
        if (data && data.code === '000000') {
          const { name, type, level, remark, status, typeName, levelName, deviceVo, maintainUserInfoVo, maintainTaskVoList } = data.data
          setVerifyTip('')
          // 设置基本信息表单默认值
          setFieldsValue({
            name,
            type,
            level,
            remark
          })
          // 页面状态
          setStatus(status)
          setPlanInfoObj({
            name,
            typeName,
            levelName,
            remark
          })
          setDeviceObj({
            deviceId: deviceVo.id,
            defaultDevice: deviceVo.deviceName,
            deviceDetail: deviceVo
          })
          setMaintainObj({
            maintainUser: maintainUserInfoVo.id,
            defaultMaintenance: `${maintainUserInfoVo.name}${maintainUserInfoVo.groupName}`,
            maintenanceMes: maintainUserInfoVo
          })
          // 设置配置保养项目的默认值
          const tablelist = maintainTaskVoList.filter(item => item.deleted !== 'Y')
          setTableData([
            ...tablelist.map((item, index) => {
              return {
                key: randomString(),
                ...item,
                name: item.taskName,
                serialNumber: index + 1,
              }
            })
          ])
        }
      }
    }
    fetchData()
  }, [id, setFieldsValue])
  // 设备信息组件ref
  const deviceRef = useRef()
  // 保养员信息组件ref
  const maintenanceRef = useRef()

  // 草稿和提交预览的验证
  function handleSubmit(flag, statusId) {
    const bool1 = (tableData.length === 0);
    const bool2 = (tableData.length > 0 && tableData.some(item => item.name === ''));
    const bool3 = (tableData.length > 0 && tableData.some(item => (item.cycle === '') || (item.cycleType === '') || (!/^[1-9]\d*$/.test(item.cycle)) || (item.cycle > 999)));
    const bool4 = (tableData.length > 0 && tableData.some(item => item.startTime === ''));
    // 验证是否选择设备信息
    deviceRef.current.validateFields()
    // 验证是否选择保养员信息
    maintenanceRef.current.validateFields()
    // 计划基本信息
    verifyProject(bool1, bool2, bool3, bool4)
    validateFields()
      .then((values) => {
        const data = {
          ...values,
          deviceId: deviceObj.deviceId,
          maintainUser: maintainObj.maintainUser
        }
        if (deviceObj.deviceId === '' || maintainObj.maintainUser === '') {
          return
        }
        if (bool1 || bool2 || bool3 || bool4) {
          return
        }
        setPlanInfoObj({
          ...planInfoObj,
          name: values.name,
          remark: values.remark
        })
        setParamsObj(data)
        if (flag === '提交预览') {
          dispatch({
            type: 'preview/updateIsshow',
            payload: {
              isShow: true,
              statusId,
            }
          })

        } else {

          addEditUpkeep(statusId, data)
        }
      })
      .catch(e => console.error(e.message))
  }
  // 验证保养项目
  function verifyProject(bool1, bool2, bool3, bool4) {
    if (bool1) {
      setVerifyTip('请配置保养项目')
      return
    }
    if (bool2 && bool3 && bool4) {
      setVerifyTip('请填写项目名称  /  请选择项目周期  /  请选择开始时间')
      return
    }
    if (bool2 && !bool3 && !bool4) {
      setVerifyTip('请填写项目名称 ')
      return
    }
    if (bool2 && bool3 && !bool4) {
      setVerifyTip('请填写项目名称  /  请选择项目周期')
      return
    }
    if (bool2 && !bool3 && bool4) {
      setVerifyTip('请填写项目名称  /  请选择开始时间')
      return
    }
    if (!bool2 && bool3 && bool4) {
      setVerifyTip('请选择项目周期  /  请选择开始时间')
      return
    }
    if (!bool2 && bool3 && !bool4) {
      setVerifyTip('请选择项目周期 ')
      return
    }
    if (!bool2 && !bool3 && bool4) {
      setVerifyTip('请选择开始时间 ')
      return
    }
    if (!bool1 && !bool2 && !bool3 && !bool4) {
      setVerifyTip('')
      return
    }
  }
  // 添加和编辑保养计划的请求
  async function addEditUpkeep(statusId, values) {
    // 过滤新增的ID
    const filterId = () => {
      if (tableData.length > 0) {
        const arr = []
        tableData.map(item => {
          if (item.new) {
            delete item.id
            delete item.new
            arr.push({ ...item })
          } else {
            arr.push({ ...item })
          }
        })
        return arr
      }
      return []
    }

    if (id === undefined) {

      const data = await addUpkeep({
        ...values,
        status: statusId,
        maintainTaskSet: filterId() // [...tableData]
      })
      dispatch({
        type: 'preview/updateIsshow',
        payload: {
          isShow: false
        }
      })
      if (data.code === '000000') {
        message.success(data.mesg, 2, () => {
          const { pathname } = location
          const panesList = panes.filter(pane => pane.key !== pathname);
          dispatch({
            type: 'headerTaps/updateHeaderTaps',
            payload: { panes: panesList },
          });
          dispatch({
            type: 'commonAction/uploadCatch',
            payload: {
              catchObj: {
                'deviceUpkeep_add': [false, true]
              }
            }
          })
          dispatch({
            type: 'deviceUpkeep/updateSerachParams',
            payload: {
              serachParams: {
                current: 1
              }
            }
          })
          router.push({
            pathname: '/deviceUpkeep',
            params: {
              isRefresh: true
            }
          })
        })
      } else {
        message.error(data.mesg)
      }
    } else {
      const data = await editUpkeep({
        data: {
          ...values,
          status: statusId,
          maintainTaskSet: filterId() // [...tableData]
        },
        id
      })
      dispatch({
        type: 'preview/updateIsshow',
        payload: {
          isShow: false
        }
      })
      dispatch({
        type: 'deviceUpkeep/updateSerachParams',
        payload: {
          serachParams: {
            current: 1
          }
        }
      })
      if (data && data.code === '000000') {
        message.success(data.mesg, 2, () => {
          const { pathname } = location
          const panesList = panes.filter(pane => pane.key !== pathname);
          dispatch({
            type: 'headerTaps/updateHeaderTaps',
            payload: { panes: panesList },
          });
          router.push({
            pathname: '/deviceUpkeep',
            params: {
              isRefresh: true
            }
          })
        })
      } else {
        // 提交审批失败
        if (data) {
          message.error(data.mesg)
          const { pathname } = location
          const panesList = panes.filter(pane => pane.key !== pathname);
          dispatch({
            type: 'headerTaps/updateHeaderTaps',
            payload: { panes: panesList },
          });
          router.push({
            pathname: '/deviceUpkeep',
            params: {
              isRefresh: true
            }
          })
        }
      }
    }
  }

  // 获取计划基本信息的保养级别和保养类型数据
  useEffect(() => {
    dispatch({
      type: 'deviceUpkeep/getQueryParameter'
    })
  }, [dispatch])

  // 获取配置设备信息的所有设备
  useEffect(() => {
    dispatch({
      type: 'dictionaryList/getDeviceList',
      payload: {
        deviceName: ''
      }
    })
  }, [dispatch])

  // 获取预置项目列表
  useEffect(() => {
    dispatch({
      type: 'dictionaryList/getPresetList',
      payload: {}
    })
  }, [dispatch])

  // 获取保养员列表
  useEffect(() => {
    dispatch({
      type: 'dictionaryList/getUserList',
      payload: {
        current: 1,
        size: 100,
        type: 4
      }
    })
  }, [dispatch])

  // 当天的时间日期之前的不可选
  function disabledDate(current) {
    return current && current < moment().subtract(1, 'day');
  }

  const columns = [
    {
      title: '序号',
      dataIndex: 'index',
      key: 'index',
      align: 'center',
      width: '0.8rem',
      render: (text, record, index) => (
        <span>{index + 1}</span>
      )
    },
    {
      title: '项目名称',
      dataIndex: 'name',
      key: 'name',
      align: 'center',
      render: (text, record) => {
        return (
          <Input onBlur={() => getBool()} className={['self-input', text === '' ? 'err-border' : ''].join(' ')} maxLength={20} value={text} placeholder="请输入" onChange={(e) => handleName(e, record.key)} />
        )
      }
    },
    {
      title: '项目描述',
      dataIndex: 'remark',
      key: 'remark',
      align: 'center',
      render: (text, record) => (
        <Input className="self-input" value={text} placeholder="请输入" maxLength={20} onChange={(e) => handleRemark(e, record.key)} />
      )
    },
    {
      title: '项目周期',
      dataIndex: 'cycle',
      key: 'cycle',
      align: 'center',
      render: (text, record) => (
        <>
          <Input
            onBlur={() => getBool()}
            className={['self-input', (text !== '' && record.cycleType !== '' && /^[1-9]\d*$/.test(text) && (text <= 999)) ? '' : 'err-border'].join(' ')}
            placeholder="请输入"
            defaultValue={text}
            value={text}
            onChange={(e) => handleCycle(e, record.key)}
          />
          <Radio.Group defaultValue={record.cycleType + ''} className="period-radio" onChange={(e) => handleCycleType(e, record.key)}>
            <Radio.Button value="1">日</Radio.Button>
            <Radio.Button value="2">周</Radio.Button>
            <Radio.Button value="3">月</Radio.Button>
          </Radio.Group>
        </>
      )
    },
    {
      title: '开始时间',
      dataIndex: 'startTime',
      key: 'startTime',
      align: 'center',
      render: (text, record) => (
        <DatePicker
          disabledDate={disabledDate}
          className={['self-date', text === '' ? 'err-border' : ''].join(' ')}
          showToday={false}
          placeholder="请选择"
          defaultValue={text === '' ? null : moment(text)}
          onChange={(date, dateString) => handleStartTime(date, dateString, record.key)}
          onOpenChange={handleOnOpenChange}
        />
      )
    },
    {
      title: '操作',
      dataIndex: 'action',
      key: 'action',
      align: 'center',
      width: '2rem',
      render: (text, record) => (
        <span className="td-blue" style={{ margin: '0' }} onClick={() => handleDelete(record)}>删除</span>
      ),
    },
  ]
  // 选择项目日期关闭的校验提示
  function handleOnOpenChange(open) {
    if (!open) {
      getBool()
    }
  }
  // 验证保养项目
  function getBool() {
    const bool1 = (tableData.length === 0);
    const bool2 = (tableData.length > 0 && tableData.some(item => item.name === ''));
    const bool3 = (tableData.length > 0 && tableData.some(item => (item.cycle === '') || (item.cycleType === '') || (!/^[1-9]\d*$/.test(item.cycle)) || (item.cycle > 999)));
    const bool4 = (tableData.length > 0 && tableData.some(item => item.startTime === ''));
    verifyProject(bool1, bool2, bool3, bool4)
  }
  // 保养项目的名称发生改变的方法
  function handleName(e, key) {
    setTableData([...tableData.map(item => {
      if (item.key === key) {
        item.name = e.target.value.replace(/\s+/g, '')
      }
      return item
    })])
  }
  // 保养项目的备注发生变化的方法
  function handleRemark(e, key) {
    setTableData([...tableData.map(item => {
      if (item.key === key) {
        item.remark = e.target.value.replace(/\s+/g, '')
      }
      return item
    })])
  }
  // 保养项目的项目周期类型发生变化的方法
  function handleCycleType(e, key) {
    setTableData([...tableData.map(item => {
      if (item.key === key) {
        item.cycleType = e.target.value
      }
      return item
    })])
    getBool()
  }
  // 保养项目的项目周期输入发生变化的方法
  function handleCycle(e, key) {
    if ((/^[1-9]\d*$/.test(e.target.value))) {
      setTableData([...tableData.map(item => {
        if (item.key === key) {
          item.cycle = e.target.value
        }
        return item
      })])
    }
  }
  function handleStartTime(date, dateString, key) {
    setTableData([...tableData.map(item => {
      if (item.key === key) {
        item.startTime = dateString
      }
      return item
    })])
    getBool()
  }
  // 获取选择的保养员
  const handleSelectUpkeeper = (value, id) => {
    const userObj = userList.find(item => item.id === Number(id))
    setMaintainObj({
      ...maintainObj,
      maintainUser: id,
      maintenanceMes: userObj
    })
  }
  // 获取选择的设备 根据选择的设备查询设备想起信息
  async function handleSelectDevice(value, id) {
    const data = await getDeviceDetail({ id })
    if (data.code === '000000') {
      setDeviceObj({
        ...deviceObj,
        deviceId: id,
        deviceDetail: data.data
      })
    } else {
      message.error(data.mesg)
      setDeviceObj({
        ...deviceObj,
        deviceId: '',
        deviceDetail: {}
      })
    }
  }
  // 选择预置项目
  const handleSelectPresetProject = (value, e) => {
    let presetObj = presetList.find(item => item.id === Number(e.key))
    if (verifyTip === '请配置保养项目') setVerifyTip('')
    tableData.length === 30 ?
      message.info('配置保养项目最多添加30个')
      :
      setTableData(
        [
          ...tableData,
          {
            key: randomString(),
            new: true,
            serialNumber: tableData.length > 0 ? tableData[tableData.length - 1].serialNumber + 1 : 1,
            ...presetObj,
            startTime: tableData.length > 0 ? tableData[tableData.length - 1].startTime : '',
          }
        ]
      )
  }
  // 添加保养项目
  function handleAddCustomPreset() {
    if (verifyTip === '请配置保养项目') setVerifyTip('')
    tableData.length === 30 ?
      message.info('配置保养项目最多添加30个')
      :
      setTableData(
        [
          ...tableData,
          {
            key: randomString(),
            new: true,
            serialNumber: tableData.length > 0 ? tableData[tableData.length - 1].serialNumber + 1 : 1,
            ...{
              name: '',
              remark: '',
              cycle: '',
              cycleType: '',
              startTime: tableData.length > 0 ? tableData[tableData.length - 1].startTime : ''
            }
          }
        ]
      )
  }
  // 删除预置项目
  const handleDelete = (record) => {
    setTableData(tableData.filter(item => item.key !== record.key).map((it, index) => {
      return {
        ...it,
        key: randomString(),
        serialNumber: index + 1
      }
    }))
  }
  // 取消按钮直接返回上个页面
  function handleCancle() {
    const { pathname } = location
    const panesList = panes.filter(pane => pane.key !== pathname);
    if (panesList.length === 0) {
      return
    }
    let prevObj = {}
    panes.forEach((item,index) => {
      if (item.key === pathname) {
        if (index) {
          prevObj = panes[index - 1]
        } else {
          prevObj = panes[index + 1]
        }
      }
    })
    dispatch({
      type: 'headerTaps/updateHeaderTaps',
      payload: { panes: panesList },
    });
    const catchName = pathname.split('/').filter(item => item !== '').join("_")
    dispatch({
      type: 'commonAction/uploadCatch',
      payload: {
        catchObj: {
          [catchName]: [false, true]
        }
      }
    })
    router.push({
      pathname: prevObj.path,
      query: prevObj.query
    })
  }
  // 提交审批方法
  function handleSubmitApproval(statusId) {
    addEditUpkeep(statusId, paramsObj)
  }
  return (
    <div className="deviceUpkeep_plan">
      <PreviewPlanModal
        userInfo={maintainObj.maintenanceMes}
        deviceInfo={deviceObj.deviceDetail}
        planInfo={planInfoObj}
        basicTitle='计划基本信息'
        deviceTitle='设备信息'
        userTitle='保养员信息'
        isCheckUser={false}
        projectList={tableData}
        addList={handleSubmitApproval}
      />
      <Form className="self-form">
        <div className="deviceUpkeep_plan-form">
          <div className="basic-message">
            <TitleLine title='计划基本信息'></TitleLine>
            <Form.Item label="计划名称" colon={false}>
              {getFieldDecorator('name', {
                rules: [
                  { required: true, message: '请输入计划名称' },
                  { max: 20, message: '最多可输入20字' }
                ],
                validateTrigger: ['onBlur', 'onChange'],
                getValueFromEvent: event => event.target.value.replace(fitterInput, '')
              })(
                <Input className="self-input" placeholder="请输入计划名称" maxLength={20} />
              )}
            </Form.Item>
            <Form.Item label="保养类型" colon={false}>
              {getFieldDecorator('type', {
                rules: [{ required: true, message: '请选择保养类型' }],
                validateTrigger: ['onBlur', 'onChange']
              })(
                <Select
                  placeholder="请选择保养类型"
                  className="self-select"
                  onChange={(val, e) => setPlanInfoObj({
                    ...planInfoObj,
                    typeName: e.key
                  })}
                  getPopupContainer={triggerNode => triggerNode.parentNode}
                >
                  {
                    parameter.maintainTypeList && parameter.maintainTypeList.length > 0 && parameter.maintainTypeList.map(item => {
                      return (
                        <Option value={item.code} key={item.desc}>{item.desc}</Option>
                      )
                    })
                  }
                </Select>
              )}
            </Form.Item>
            <Form.Item label="保养级别" colon={false}>
              {getFieldDecorator('level', {
                rules: [
                  { required: true, message: '请选择保养级别' }
                ],
                validateTrigger: ['onBlur', 'onChange']
              })(
                <Select
                  placeholder="请选择保养级别"
                  className="self-select"
                  onChange={(val, e) => setPlanInfoObj({
                    ...planInfoObj,
                    levelName: e.key
                  })}
                  getPopupContainer={triggerNode => triggerNode.parentNode}
                >
                  {
                    parameter.maintainLevelList && parameter.maintainLevelList.length > 0 && parameter.maintainLevelList.map(item => {
                      return (
                        <Option value={item.code} key={item.desc}>{item.desc}</Option>
                      )
                    })
                  }
                </Select>
              )}
            </Form.Item>
            <Form.Item label="计划描述" colon={false} className='planDescri'>
              {getFieldDecorator('remark', {
                initialValue: '',
                rules: [
                  { required: false, message: '请输入计划描述' },
                  { max: 20, message: '最多可输入20字' }
                ],
                validateTrigger: ['onBlur', 'onChange'],
                getValueFromEvent: event => event.target.value.replace(fitterInput, '')
              })(
                <Input.TextArea className="self-input self-area" placeholder="请输入计划描述" maxLength={20} />
              )}
            </Form.Item>
          </div>


          {/* 配置设备信息 */}
          <div className="maintenance-device">
            <RefDeviceMessage
              ref={deviceRef}
              show={true}
              title='配置保养设备'
              handleSelect={handleSelectDevice}
              deviceList={deviceList}
              deviceInfo={deviceObj.deviceDetail}
              defaultVal={deviceObj.defaultDevice}
              isDetail={false}
            />
          </div>

          {/* 配置保养员 */}
          <div className="maintenance-message">
            <RefMaintenanceMesssage
              ref={maintenanceRef}
              show={true}
              title="配置保养员"
              person="保养员"
              handleSelect={handleSelectUpkeeper}
              userList={userList}
              maintenanceInfo={maintainObj.maintenanceMes}
              defaultVal={maintainObj.defaultMaintenance}
            />
          </div>
        </div>


        {/* 配置保养项目 */}
        <div className="deviceUpkeep_plan-table">
          <div className="table-header">
            <TitleLine title="配置保养项目"></TitleLine>
            <div className="presetProject">
              <Form.Item label="选择预置项目">
                {getFieldDecorator('maintainTaskSet', {
                  rules: [{ required: false, message: '请选择' }],
                })(
                  <Select
                    placeholder="请选择"
                    className="self-select"
                    onSelect={handleSelectPresetProject}
                    getPopupContainer={triggerNode => triggerNode.parentNode}
                  >
                    {
                      presetList.length > 0 && presetList.map((item, index) => {
                        return (
                          <Option value={item.name} key={item.id}>{item.name}</Option>
                        )
                      })
                    }
                  </Select>
                )}
              </Form.Item>
              <Button className="white-button" onClick={handleAddCustomPreset}>添加自定义项目</Button>
              <span className="tip">只可选择台账状态【启用】的设备</span>
            </div>
          </div>
          <Table
            columns={columns}
            dataSource={tableData}
            pagination={false}
            className="self-table"
            bordered={true}
          />
          <div className="table-tip">
            {verifyTip}
          </div>
        </div>
        <div className="form-btn">
          <Button className="orange-button" onClick={() => handleSubmit('提交预览', 1)}>提交预览</Button>
          {
            (status === 5) || (id === undefined) ?
              <Button
                className="blue-button"
                onClick={() => handleSubmit('存草稿', 5)}
              >存草稿</Button>
              :
              null
          }

          <Button className="white-button" onClick={handleCancle}>取消</Button>
        </div>
      </Form>
    </div>
  )
}
export default connect(({ deviceUpkeep, dictionaryList, preview, headerTaps, commonAction }) => ({
  deviceUpkeep, dictionaryList, preview, headerTaps, commonAction
}))(withRouter(Form.create()(Plan)))

